package com.ljdemo.timemanager.ui.screen.mainnav.home

import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.ljdemo.timemanager.model.DataStoreCont
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.time.LocalDateTime
import javax.inject.Inject

// 密封类相当于枚举扩展
sealed class UIIntent{
    data class ChangeImmersionState(val value:Boolean):UIIntent()
    data class ChangeLoadingState(val value:Boolean):UIIntent()
}

@HiltViewModel
class HomeViewModel @Inject constructor (
    private val dataStore: DataStore<Preferences>
        ):ViewModel(){
    private val weekList= listOf<String>("一","二","三","四","五","六","天")
    private var _dateState= MutableStateFlow(DateState())
    val dateState=_dateState
    private var _timeState= MutableStateFlow(TimeState())
    val timeState=_timeState
    private var _uiState= MutableStateFlow(UIState())
    val uiState=_uiState
    init {
        initTime()
        // 开启协程
        viewModelScope.launch {
            // 初始化时获取保存的沉浸式状态
            initImmersionState()
        }
    }

    // 获取保存的沉浸式状态
    private suspend fun initImmersionState() = withContext(Dispatchers.IO){
        // 获取保存在dataStore中key为DataStoreCont.IMMERSION_STATE的值，默认值为false
        dataStore.data.map {
            it[DataStoreCont.IMMERSION_STATE] ?:false
        }.first().takeIf { it }?.let {
            // 如果值为true
            _uiState.apply {
                value=value.copy(immersionShow = true)
            }
        }?:let {
            // 如果值为false
            _uiState.apply {
                value=value.copy(immersionShow = false)
            }
        }
    }

    fun sendUIIntent(uiIntent: UIIntent){
        when(uiIntent){
            is UIIntent.ChangeImmersionState -> _uiState.apply {
                value=value.copy(immersionShow = uiIntent.value)
                // 修改 沉浸式 时，开启协程，保存状态到 dataStore
                viewModelScope.launch(Dispatchers.IO) {
                    dataStore.edit {
                        // 保存状态 ( it.set... )
                        it[DataStoreCont.IMMERSION_STATE]=uiIntent.value
                    }
                }
            }
            is UIIntent.ChangeLoadingState -> _uiState.apply {
                value=value.copy(loadingShow = uiIntent.value)
            }
        }
    }
    private fun initTime(){
        // 获取当前时间，并传入回调方法进行操作，apply的回调中, this 代表调用apply的对象，apply方法返回调用它的对象
        LocalDateTime.now().apply {
            // 调用also对_timeState进行操作，并传入回调方法，also的回调中，会将调用also的对象作为参数传递给回调函数，also返回调用它的对象
            _timeState.also { timeState->
                timeState.value=
                    timeState.value.copy(hour = hour, minute = minute, second = second)
            }
            _uiState.also { uiState ->
                uiState.value=
                    uiState.value.copy(timeMode = if (hour>12) TimeMode.PM else TimeMode.AM)
            }
        }
        updateTime()
        updateDateAndWeek()
    }

    private fun updateDateAndWeek(){
        LocalDateTime.now().apply {
            _dateState.also { dateState ->
                dateState.value=
                    dateState.value.copy(
                        date = "$year/$monthValue/$dayOfMonth",
                        week = "(${weekList[dayOfWeek.value - 1]})"
                    )
            }
        }
    }

    private fun updateTime(){
        //开启协程
        viewModelScope.launch(Dispatchers.IO) {
            _timeState.apply {
                while(true){
                    val nowSecond=value.second+1
                    if (nowSecond==60){
                        value=value.copy(second = 0)
                        val nowMinute=value.minute+1
                        if (nowMinute==60){
                            value=value.copy(minute = 0)
                            val nowHour=value.hour+1
                            val timeMode=if (nowHour>12){ // if赋值类似于 ? :
                                TimeMode.PM
                            }else{
                                TimeMode.AM
                            }
                            _uiState.value=_uiState.value.copy(timeMode = timeMode)
                            value = if (nowHour==24){
                                updateDateAndWeek() //更新日期和星期
                                value.copy(hour = 0)
                            }else{
                                value.copy(hour = nowHour)
                            }
                        }else{
                            value=value.copy(minute = nowMinute)
                        }
                    }else{
                        value=value.copy(second = nowSecond)
                    }
                    delay(1000)
                }
            }
        }
    }

}